#pragma once;
#include "util.hpp"
#include <sstream>
namespace cloud
{
	class DataManager
	{
	private:
		std::string _backup_file; 
		std::unordered_map<std::string, std::string> _table;
	public:
		DataManager(const std::string& backup_file)
			:_backup_file(backup_file)
		{}

		bool Storage()
		{
			std::stringstream ss;
			// 1. get all backup info 
			auto it = _table.begin();
			while (it != _table.end())
			{
				// 2. key val\n  key val\n  key val\n
				ss << it->first << " " << it->second << std::endl;
				it++;
			}
			// 3. persistence storage
			FileUtil fu(_backup_file);
			fu.SetContent(ss.str());
			return true;
		}

		int Split(const std::string& str, const std::string& sep, std::vector<std::string>& arry)
		{
			int count = 0;
			size_t pos = 0;
			size_t idx = 0;
			while (1)
			{
				pos = str.find(sep, idx);
				if (pos == std::string::npos)
				{
					break;
				}
				if (pos == idx)
				{
					idx = pos + sep.size();
					continue;
				}
				std::string tmp = str.substr(idx, pos - idx);
				arry.push_back(tmp);
				count++;
				idx = pos + sep.size();
			}

			if (idx < str.size())
			{
				arry.push_back(str.substr(idx));
				count++;
			}

			return count;
		}

		bool InitLoad()
		{
			// 1. get all data from file 
			FileUtil fu(_backup_file);
			std::string body;
			fu.GetContent(body);
			// 2. analysis the string and add info to table
			std::vector<std::string> arry;
			Split(body, "\n", arry);
			for (auto a : arry)
			{
				std::vector<std::string> tmp;
				Split(a, " ", tmp);
				if (tmp.size() != 2)
				{
					continue;
				}
				_table[tmp[0]] = tmp[1];
			}
			return true;
		}


		bool Insert(const std::string& key, const std::string& val)
		{
			_table[key] = val;
			Storage();
			return true;
		}
		bool Update(const std::string& key, const std::string& val)
		{
			_table[key] = val;
			Storage();
			return true;
		}
		bool GetOneByKey(const std::string& key , std::string& val)
		{
			auto it = _table.find(key);
			if (it == _table.end())
			{
				return false;
			}
			val = it->second;
			return true;
		}

	};
}